#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
    PySeq0 - A Python Sequenzer
    by Tobias Sauer 2011
    Copyright: GPL v2
    http://www.leichtdio.de
    
    @ToDo:
        - Wenn mehrere Loops in einem Beat: Wie Drum behandeln > DrumClass anpassen
"""

#import xml.dom.minidom as minidom
import logging
_log = logging.getLogger("pyseq0.lmms")

import xml.etree.ElementTree as ET
import json

class Tools:
    def parseElement(self, ETElement):
        dic = {}
        for couple in ETElement.items():
            dic[couple[0]] = couple[1]
        return dic

class DrumPattern:
    """
        Debug Klasse für den LMMS2json Converter
    """
    def __init__(self, element):
        parsdic = Tools().parseElement(element)
        self.name = parsdic["name"]
        self.pos = parsdic["pos"]
        self.length = int(parsdic["len"]) / 192
        self.steps = int(parsdic["steps"])
        self.stepfaktor = 192 / int(parsdic["steps"])
        self.spur = {}
        self.spur[self.name] = self.note2string(element.getchildren())

    def note2string (self, notes):
        drumstring = []
        for step in xrange(self.steps):
            drumstring.append("-")
        for note in notes:
            drumstring[(int(Tools().parseElement(note)["pos"]) / self.stepfaktor)] = "X"
        _log.debug("%s, %s", self.name, "".join(drumstring))
        return "".join(drumstring)

    def add(self, element):
        parsdic = Tools().parseElement(element)
        self.name = parsdic["name"]
        self.spur[self.name] = self.note2string(element.getchildren())

    def get_dict(self):
        return {
             "name" : "beat %s" %(self.pos),
             "content" : self.spur
            }

class LoopPattern:
    """
        Debug Klasse für den LMMS2json Converter
    """
    def __init__(self, element):
        parsdic = Tools().parseElement(element)
        self.name = parsdic["name"]
        self.length = int(parsdic["len"]) / 192
        self.notes = []
        self.addnote(element.getchildren())

    def addnote (self, noteList):
        lastpos = 0
        sum_time = 0.
        for note in noteList:
            notedic = Tools().parseElement(note)
            if int(notedic["vol"]) > 100:
                notedic["vol"] = "100"
            velocity = 127 / (100 / int(notedic["vol"]))
            key = int(notedic["key"]) + 12
            length = float(notedic["len"]) / 192.
            # Auf Pause testen und dann Pause einfügen
            sum_time += length
            if (lastpos + int(notedic["len"])) != int(notedic["pos"]) \
                and lastpos != 0:
                timetosleep = float(notedic["pos"]) - (lastpos + int(notedic["len"]))
                self.notes.append(["sleep", float(timetosleep) / 192.])
                sum_time += timetosleep / 192
            # Note setzen
            lastpos = int(notedic["pos"])
            self.notes.append([key, velocity, 0, length])
        if sum_time < self.length:
            self.notes.append(["sleep", float(self.length-sum_time)])

    def get_dict(self):
        jsondic = {
             "autoconnect": True,
             "name": self.name,
             "midiport": -1,
             "length": self.length,
             "midiname": self.name,
             "channel": 0,
             "content":self.notes
            }
        return jsondic

class Lmms:
    """
        LMMS - mmp 2 json Converter
        Übersetzt mmp-Datein in für pyseq0 lesbare JSON Datein
    """
    def mmp2json (self, xmlfile):
        """
            Use ElementTree to Convert MMP 2 JSON
        """
        
        tree = ET.parse(xmlfile)
        looplist = []
        # LoopList
        for entry in tree.getiterator("pattern"):
            if int(entry.get("type")) == 1:
                looplist.append(LoopPattern(entry).get_dict())
        # /LoopList
        
        # DrumList
        drumclassdic = {}
        for entry in tree.getiterator("pattern"):
            if int(entry.get("type")) == 0 and len(entry.getchildren()):
                tmpentrydic = Tools().parseElement(entry)
                tmp_pos = tmpentrydic["pos"]
                if drumclassdic.has_key(tmp_pos):
                    drumclassdic[tmp_pos].add(entry)
                else:
                    drumclassdic[tmp_pos] = DrumPattern(entry)

        _log.debug("%s", drumclassdic)
        drumlist = []
        for drumclass in drumclassdic:
            drumlist.append(drumclassdic[drumclass].get_dict())
            #drumlist.append()
        # /DrumList

        # BPM
        bpm = int(Tools().parseElement(tree.find("head"))["bpm"])
        # /BPM

        # Letzte Abfragen:
        songname = raw_input('Songname ?> ')
        copyright = raw_input('copyright ?> ')
        author = raw_input('author ?> ')
        return json.dumps({
    "bpm": bpm,
    "name": songname,
    "copyright": copyright,
    "author": author,
    "generator" : "pyseq0",
    "drums":drumlist,
    "loops":looplist
    })

if __name__ == "__main__":
    from pprint import pprint
    debug = Lmms()
    pprint(debug.mmp2json("helpme.mmp"))
